#include "GamePlayState.h"

#include "../../Game.h"

#include "../MenuSystem/MainMenuState.h"
#include "../../ObjectManager/ObjectManager.h"
#include "../../Tokens/PlayerToken.h"
#include "../../Tokens/EnemyToken.h"
#include "../../Tokens/BossToken.h"
#include "../../Tokens/PickUpToken.h"

#include "../../SGD Wrappers/CSGD_Direct3D.h"
#include "../../SGD Wrappers/CSGD_DirectInput.h"
#include "../../SGD Wrappers/CSGD_TextureManager.h"
#include "../../SGD Wrappers/CSGD_XAudio2.h"

#include "../../../Source/ParticleSystem/EmitterManager.h"
#include "../../../Source//ParticleSystem/IEmitter.h"
#include "../../AnimationSystem/Animation.h"

#include "../../ScriptingSystem/ScriptManager.h"
#include "../../ScriptingSystem/InitEnemyScript.h"

using std::wostringstream;

CGamePlayState* CGamePlayState::GetInstance( void )
{
	static CGamePlayState s_Instance;

	return &s_Instance;
}

CGamePlayState::CGamePlayState( void )
{
	m_pD3D		= nullptr;
	m_pDI		= nullptr;
	m_pTM		= nullptr;
	m_pXA		= nullptr;
	m_pOM		= nullptr;

	m_sSongID				= -1;
	m_sSoundEffectID		= -1;
	m_sPlayerImgID			= -1;
	m_sGroundEnemyImgID		= -1;
	m_sAirEnemyImgID		= -1;
	m_sMageEnemyImgID		= -1;
	m_sSentinelEnemyImgID	= -1;
	m_sBossImgID			= -1;
	m_sPickUpImgID			= -1;


//	Animation *testAnimation1 = new Animation();
	/*Animation *testAnimation2 = new Animation();
	//note: test only

	Animation *testAnimation2 = new Animation();
	Animation *testAnimation3 = new Animation();
	Animation *testAnimation4 = new Animation();
	Animation *testAnimation5 = new Animation();*/
	//
//	this->m_vTestAnimation.push_back(testAnimation1);
	//this->m_vTestAnimation.push_back(testAnimation2);
	//this->m_vTestAnimation.push_back(testAnimation3);
	//this->m_vTestAnimation.push_back(testAnimation4);
	//this->m_vTestAnimation.push_back(testAnimation5);

		testEManager = new CEmitterManager();
	testEManager->Load();

	
	
}

CGamePlayState::~CGamePlayState( void )
{
	m_pD3D		= nullptr;
	m_pDI		= nullptr;
	m_pTM		= nullptr;
	m_pXA		= nullptr;
	m_pOM		= nullptr;
	m_pSM		= nullptr;

	// Testing purposes
	m_pEnemyScript = nullptr;

	m_sSongID				= -1;
	m_sSoundEffectID		= -1;

	//note: test only
	delete testEManager;

	for(unsigned int i = 0; i < m_vTestAnimation.size(); i++)
		delete m_vTestAnimation[i];
}

void CGamePlayState::Enter( void )
{
	m_pD3D		= CSGD_Direct3D::GetInstance();
	m_pDI		= CSGD_DirectInput::GetInstance();
	m_pTM		= CSGD_TextureManager::GetInstance();
	m_pXA		= CSGD_XAudio2::GetInstance();
	m_pOM		= CObjectManager::GetInstance();
	m_pSM		= CScriptManager::GetInstance();

	m_sSongID				= 0;
	m_sSoundEffectID		= 0;
	 
	m_sPlayerImgID			= m_pTM->LoadTexture( _T( "resource/Tokens/JPC_Ship_Idle.png" ), D3DCOLOR_XRGB( 255, 0, 255 ) );
	m_sGroundEnemyImgID		= m_pTM->LoadTexture( _T( "resource/Tokens/orc.png" ) );
	m_sAirEnemyImgID		= m_pTM->LoadTexture( _T( "resource/Tokens/ag_devil.png" ) );
	m_sMageEnemyImgID		= m_pTM->LoadTexture( _T( "resource/Tokens/mage_clown.png" ) );
	m_sSentinelEnemyImgID	= m_pTM->LoadTexture( _T( "resource/Tokens/evil_armor.png" ) );
	m_sBossImgID			= m_pTM->LoadTexture( _T( "resource/Tokens/blue-dragon-sprite.jpg" ), D3DCOLOR_XRGB( 255, 255, 255 ) );
	m_sPickUpImgID			= m_pTM->LoadTexture( _T( "resource/Tokens/health-pack.png" ) );

	// Initialize Lua
	m_pSM->InitializeLua();

	// Make a new init enemy script
	m_pEnemyScript = new CInitEnemyScript();

	// Load the script
	m_pSM->Store( m_pEnemyScript, "InitEnemy" );

	////////////////////////////////////////////////////
	// Object manager testing purposes:
	// Create a local player token

	std::list< CBaseTile* > m_lTiles;
	m_pTileM->LoadTileInfo( m_lTiles );

	std::list< CBaseTile* >::iterator iter;

	for( iter = m_lTiles.begin(); iter != m_lTiles.end(); iter++ )
	{
		m_pOM->AddObject( (*iter) );
		(*iter)->Release();
	}

	PlayerToken* pPlayer = new PlayerToken;
	
	// Set data members
	pPlayer->SetHealth( 100 );
	pPlayer->SetPosX( 100 );
	pPlayer->SetPosY( 100 );
	pPlayer->SetWidth( 64 );
	pPlayer->SetHeight( 64 );
	pPlayer->SetImageID( m_sPlayerImgID );
	pPlayer->SetSpeed( 250 );

	// Add the player to the Object Manager
	m_pOM->AddObject( pPlayer );

	// release and nullify the player pointer
	pPlayer->Release();
	pPlayer = nullptr;

	// Create an Ground enemy
	EnemyToken* pGround = new EnemyToken;
	
	// Set data members
	pGround->SetImageID( m_sGroundEnemyImgID );
	pGround->InitFromScript( m_pSM->GetScript( "InitEnemy" ), EnemyToken::EnenmyIDs::Ground );

	// Add the ground enemy to the Object Manager
	m_pOM->AddObject( pGround );

	// release and nullify the ground enemy pointer
	pGround->Release();
	pGround = nullptr;

	// Create an Air enemy
	EnemyToken* pAir = new EnemyToken;
	
	// Set data members
	pAir->SetImageID( m_sAirEnemyImgID );
	pAir->InitFromScript( m_pSM->GetScript( "InitEnemy" ), EnemyToken::EnenmyIDs::Air );

	// Add the air enemy to the Object Manager
	m_pOM->AddObject( pAir );

	// release and nullify the air enemy pointer
	pAir->Release();
	pAir = nullptr;

	// Create an Mage enemy
	EnemyToken* pMage = new EnemyToken;
	
	// Set data members
	pMage->SetImageID( m_sMageEnemyImgID );
	pMage->InitFromScript( m_pSM->GetScript( "InitEnemy" ), EnemyToken::EnenmyIDs::Mage );

	// Add the mage enemy to the Object Manager
	m_pOM->AddObject( pMage );

	// release and nullify the mage enemy pointer
	pMage->Release();
	pMage = nullptr;

	// Create an Sentinel enemy
	EnemyToken* pSentinel = new EnemyToken;
	
	// Set data members
	pSentinel->SetImageID( m_sSentinelEnemyImgID );
	pSentinel->InitFromScript( m_pSM->GetScript( "InitEnemy" ), EnemyToken::EnenmyIDs::Sentinel );

	// Add the sentinel enemy to the Object Manager
	m_pOM->AddObject( pSentinel );

	// release and nullify the sentinel enemy pointer
	pSentinel->Release();
	pSentinel = nullptr;

	// Create a Boss
	CBossToken* pBoss = new CBossToken;
	
	// Set data members
	pBoss->SetHealth( 1000 );
	pBoss->SetPosX( 300 );
	pBoss->SetPosY( 300 );
	pBoss->SetWidth( 128 );
	pBoss->SetHeight( 128 );
	pBoss->SetImageID( m_sBossImgID );
	pBoss->SetSpeed( 250 );

	// Add the boss to the Object Manager
	m_pOM->AddObject( pBoss );

	// release and nullify the boss pointer
	pBoss->Release();
	pBoss = nullptr;

	// Create a Pick-up
	CPickUpToken* pPickUp = new CPickUpToken;
	
	// Set data members
	pPickUp->SetPosX( 100 );
	pPickUp->SetPosY( 300 );
	pPickUp->SetWidth( 32 );
	pPickUp->SetHeight( 32 );
	pPickUp->SetImageID( m_sPickUpImgID );

	// Add the player to the Object Manager
	m_pOM->AddObject( pPickUp );

	// release and nullify the player pointer
	pPickUp->Release();
	pPickUp = nullptr;
	//////////////////////////////////////////////////////

	// Set master volumes for the XAudio2 engine
	m_pXA->MusicSetMasterVolume	( m_pXA->MusicGetMasterVolume() );
	m_pXA->SFXSetMasterVolume	( m_pXA->SFXGetMasterVolume() );

	
	//for(unsigned int i=0; i < m_vTestAnimation.size();i++)
	//{
	//	m_vTestAnimation[i]->Initialize();
	//	m_vTestAnimation[i]->PlayAnimation(1.0f, true, i);
	//}

	//note: test only
	testEManager->GetEmitter(0)->PosX(100);
	testEManager->GetEmitter(0)->PosY(100);
	testEManager->GetEmitter(0)->StartEmission();
	testEManager->GetEmitter(1)->PosX(450);
	testEManager->GetEmitter(1)->PosY(200);
	testEManager->GetEmitter(1)->StartEmission();
	testEManager->GetEmitter(2)->PosX(100);
	testEManager->GetEmitter(2)->PosY(400);
	testEManager->GetEmitter(2)->StartEmission();
	testEManager->GetEmitter(3)->PosX(500);
	testEManager->GetEmitter(3)->PosY(500);
	testEManager->GetEmitter(3)->StartEmission();
	

	for(unsigned int i=0; i < m_vTestAnimation.size();i++)
	{
		m_vTestAnimation[i]->Initialize();
		m_vTestAnimation[i]->PlayAnimation(1.0f, true);
	}
}

void CGamePlayState::Exit( void )
{
	//m_pXA->MusicStopSong	( m_sSongID );
	//m_pXA->MusicUnloadSong	( m_sSongID );

	//m_pXA->SFXStopSound		( m_sSoundEffectID );
	//m_pXA->SFXUnloadSound	( m_sSoundEffectID );

	m_pOM->RemoveAllObjects();
	m_pOM->DeleteInstance();

	// Shutdown Lua
	m_pSM->ShutdownLua();

	m_pTM->UnloadTexture( m_sPlayerImgID );
	m_pTM->UnloadTexture( m_sGroundEnemyImgID );
	m_pTM->UnloadTexture( m_sAirEnemyImgID );
	m_pTM->UnloadTexture( m_sMageEnemyImgID );
	m_pTM->UnloadTexture( m_sSentinelEnemyImgID );
	m_pTM->UnloadTexture( m_sBossImgID );
	m_pTM->UnloadTexture( m_sPickUpImgID );

	m_pD3D	= nullptr;
	m_pDI	= nullptr;
	m_pTM	= nullptr;
	m_pXA	= nullptr;
	m_pOM	= nullptr;
	m_pSM	= nullptr;

	m_sSongID				= -1;
	m_sSoundEffectID		= -1;
	m_sPlayerImgID			= -1;
	m_sGroundEnemyImgID		= -1;
	m_sAirEnemyImgID		= -1;
	m_sMageEnemyImgID		= -1;
	m_sSentinelEnemyImgID	= -1;
	m_sBossImgID			= -1;
	m_sPickUpImgID			= -1;

	// delete the Init enemy script
	delete m_pEnemyScript;
	m_pEnemyScript = nullptr;
}

bool CGamePlayState::Input( void )
{
	if( m_pDI->KeyPressed( DIK_ESCAPE ) == true )
	{
		CGame::GetInstance()->ChangeState( CMainMenuState::GetInstance() );
	}

	return true;
}

void CGamePlayState::Update( float fElapsedTime )
{
	//note: test only
	//testEManager->GetEmitter(0)->Update(fElapsedTime);
	testEManager->Emitters()[0]->Update(fElapsedTime);
	testEManager->Emitters()[1]->Update(fElapsedTime);
	testEManager->Emitters()[2]->Update(fElapsedTime);
	testEManager->Emitters()[3]->Update(fElapsedTime);

	for(unsigned int i=0; i < m_vTestAnimation.size();i++)
	m_vTestAnimation[i]->Update(fElapsedTime);

	m_pOM->UpdateAllObjects( fElapsedTime );
	m_pOM->CheckCollisions();
}

void CGamePlayState::Render( void )
{

	// note:test only
	testEManager->Emitters()[0]->Render();
	testEManager->Emitters()[1]->Render();
	testEManager->Emitters()[2]->Render();
	testEManager->Emitters()[3]->Render();
	m_pOM->RenderAllObjects();

	for(unsigned int i=0; i < m_vTestAnimation.size();i++)
		m_vTestAnimation[i]->Render(500,100+i*75,false,1.0f, D3DCOLOR_XRGB(255,255,255));

}
